{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0",
   "metadata": {},
   "source": [
    "# PDFConverter - optional\n",
    "\n",
    "This script demonstrates the use of the `PDFConverter` for generating PDFs in two different modes:\n",
    "\n",
    "- **Template-Based PDF Generation**: Utilize a YAML template to render dynamic content into a PDF.\n",
    "- **Direct Prompt PDF Generation**: Convert plain string prompts into PDFs without using a template.\n",
    "\n",
    "The `PromptSendingAttack` is used to handle the interaction with the `PDFConverter` and the mock `TextTarget` target system.\n",
    "\n",
    "## Key Features\n",
    "\n",
    "1. **Template-Based Generation**:\n",
    "   - Populate placeholders in a YAML-based template using dynamic data.\n",
    "   - Convert the rendered content into a PDF using the `PDFConverter`.\n",
    "\n",
    "2. **String-Based Generation**:\n",
    "   - Accept plain string prompts directly.\n",
    "   - Generate PDFs from the provided string without using any template."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'__type__': 'TextTarget', '__module__': 'pyrit.prompt_target.text_target'}: user: C:\\git\\pyrit2\\PyRIT\\dbdata\\prompt-memory-entries\\urls\\1764136202221926.pdf\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[PromptSendingAttack (ID: e208ce53)] No response received on attempt 1 (likely filtered)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m\u001b[34m🔹 Turn 1 - USER\u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[36m   Original:\u001b[0m\n",
      "\u001b[37m  {'hiring_manager_name': 'Jane Doe', 'current_role': 'AI Engineer', 'company': 'CyberDefense Inc.',\u001b[0m\n",
      "\u001b[37m      'red_teaming_reason': 'to creatively identify security vulnerabilities while enjoying free\u001b[0m\n",
      "\u001b[37m      coffee', 'applicant_name': 'John Smith'}\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  C:\\git\\pyrit2\\PyRIT\\dbdata\\prompt-memory-entries\\urls\\1764136202221926.pdf\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "import pathlib\n",
    "\n",
    "from pyrit.common.path import CONVERTER_SEED_PROMPT_PATH\n",
    "from pyrit.executor.attack import (\n",
    "    AttackConverterConfig,\n",
    "    ConsoleAttackResultPrinter,\n",
    "    PromptSendingAttack,\n",
    ")\n",
    "from pyrit.models import SeedPrompt\n",
    "from pyrit.prompt_converter import PDFConverter\n",
    "from pyrit.prompt_normalizer import PromptConverterConfiguration\n",
    "from pyrit.prompt_target import TextTarget\n",
    "from pyrit.setup import IN_MEMORY, initialize_pyrit\n",
    "\n",
    "initialize_pyrit(memory_db_type=IN_MEMORY)\n",
    "\n",
    "prompt_data = {\n",
    "    \"hiring_manager_name\": \"Jane Doe\",\n",
    "    \"current_role\": \"AI Engineer\",\n",
    "    \"company\": \"CyberDefense Inc.\",\n",
    "    \"red_teaming_reason\": \"to creatively identify security vulnerabilities while enjoying free coffee\",\n",
    "    \"applicant_name\": \"John Smith\",\n",
    "}\n",
    "\n",
    "# Load the YAML template for the PDF generation\n",
    "template_path = (\n",
    "    pathlib.Path(CONVERTER_SEED_PROMPT_PATH) / \"pdf_converters\" / \"red_teaming_application_template.yaml\"\n",
    ")\n",
    "if not template_path.exists():\n",
    "    raise FileNotFoundError(f\"Template file not found: {template_path}\")\n",
    "\n",
    "# Load the SeedPrompt from the YAML file\n",
    "prompt_template = SeedPrompt.from_yaml_file(template_path)\n",
    "\n",
    "# Initialize the Azure OpenAI chat target (or mock target if not needed)\n",
    "prompt_target = TextTarget()\n",
    "\n",
    "# Initialize the PDFConverter\n",
    "pdf_converter = PromptConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        PDFConverter(\n",
    "            prompt_template=prompt_template,\n",
    "            font_type=\"Arial\",\n",
    "            font_size=12,\n",
    "            page_width=210,\n",
    "            page_height=297,\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=pdf_converter,\n",
    ")\n",
    "\n",
    "# Define a single prompt for the attack\n",
    "prompt = str(prompt_data)\n",
    "\n",
    "# Initialize the attack\n",
    "attack = PromptSendingAttack(\n",
    "    objective_target=prompt_target,  # Target system (Azure OpenAI or other LLM target)\n",
    "    attack_converter_config=converter_config,  # Attach the PDFConverter\n",
    ")\n",
    "\n",
    "result = await attack.execute_async(objective=prompt)  # type: ignore\n",
    "await ConsoleAttackResultPrinter().print_conversation_async(result=result)  # type: ignore"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2",
   "metadata": {},
   "source": [
    "# Direct Prompt PDF Generation (No Template)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'__type__': 'TextTarget', '__module__': 'pyrit.prompt_target.text_target'}: user: C:\\git\\pyrit2\\PyRIT\\dbdata\\prompt-memory-entries\\urls\\1764136208011709.pdf\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[PromptSendingAttack (ID: ef9d3df7)] No response received on attempt 1 (likely filtered)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m\u001b[34m🔹 Turn 1 - USER\u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[36m   Original:\u001b[0m\n",
      "\u001b[37m  This is a simple test string for PDF generation. No templates here!\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  C:\\git\\pyrit2\\PyRIT\\dbdata\\prompt-memory-entries\\urls\\1764136208011709.pdf\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# Define a simple string prompt (no templates)\n",
    "prompt = \"This is a simple test string for PDF generation. No templates here!\"\n",
    "\n",
    "# Initialize the TextTarget (mock target for testing)\n",
    "prompt_target = TextTarget()\n",
    "\n",
    "# Initialize the PDFConverter without a template\n",
    "pdf_converter = PromptConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        PDFConverter(\n",
    "            prompt_template=None,  # No template provided\n",
    "            font_type=\"Arial\",\n",
    "            font_size=12,\n",
    "            page_width=210,\n",
    "            page_height=297,\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=pdf_converter,\n",
    ")\n",
    "\n",
    "# Initialize the attack\n",
    "attack = PromptSendingAttack(\n",
    "    objective_target=prompt_target,\n",
    "    attack_converter_config=converter_config,\n",
    ")\n",
    "\n",
    "result = await attack.execute_async(objective=prompt)  # type: ignore\n",
    "await ConsoleAttackResultPrinter().print_conversation_async(result=result)  # type: ignore"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "# Modify Existing PDF with Injection Items"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[21:53:56][893][ai-red-team][INFO][Processing page 0 with 2 injection items.]\n",
      "[21:53:56][898][ai-red-team][INFO][Processing page 1 with 2 injection items.]\n",
      "[21:53:56][901][ai-red-team][INFO][Processing page 2 with 2 injection items.]\n",
      "{'__type__': 'TextTarget', '__module__': 'pyrit.prompt_target.text_target'}: user: C:\\git\\pyrit2\\PyRIT\\dbdata\\prompt-memory-entries\\urls\\1764136436903484.pdf\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[PromptSendingAttack (ID: bb7d21e1)] No response received on attempt 1 (likely filtered)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m\u001b[34m🔹 Turn 1 - USER\u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[36m   Original:\u001b[0m\n",
      "\u001b[37m  This is a simple test string for PDF generation. No templates here!\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  C:\\git\\pyrit2\\PyRIT\\dbdata\\prompt-memory-entries\\urls\\1764136436903484.pdf\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "import tempfile\n",
    "from pathlib import Path\n",
    "\n",
    "import requests\n",
    "\n",
    "from pyrit.prompt_converter import PDFConverter\n",
    "from pyrit.prompt_target import TextTarget\n",
    "from pyrit.setup import IN_MEMORY, initialize_pyrit\n",
    "\n",
    "initialize_pyrit(memory_db_type=IN_MEMORY)\n",
    "\n",
    "# This file isn't copied to our pipeline\n",
    "url = \"https://raw.githubusercontent.com/Azure/PyRIT/main/pyrit/datasets/prompt_converters/pdf_converters/fake_CV.pdf\"\n",
    "\n",
    "with tempfile.NamedTemporaryFile(delete=False, suffix=\".pdf\") as tmp_file:\n",
    "    response = requests.get(url)\n",
    "    tmp_file.write(response.content)\n",
    "\n",
    "cv_pdf_path = Path(tmp_file.name)\n",
    "\n",
    "# Define injection items\n",
    "injection_items = [\n",
    "    {\n",
    "        \"page\": 0,\n",
    "        \"x\": 50,\n",
    "        \"y\": 700,\n",
    "        \"text\": \"Injected Text\",\n",
    "        \"font_size\": 12,\n",
    "        \"font\": \"Helvetica\",\n",
    "        \"font_color\": (255, 0, 0),\n",
    "    },  # Red text\n",
    "    {\n",
    "        \"page\": 1,\n",
    "        \"x\": 100,\n",
    "        \"y\": 600,\n",
    "        \"text\": \"Confidential\",\n",
    "        \"font_size\": 10,\n",
    "        \"font\": \"Helvetica\",\n",
    "        \"font_color\": (0, 0, 255),\n",
    "    },  # Blue text\n",
    "]\n",
    "\n",
    "# Define a simple string prompt (no templates)\n",
    "prompt = \"This is a simple test string for PDF generation. No templates here!\"\n",
    "\n",
    "# Initialize the TextTarget (mock target for testing)\n",
    "prompt_target = TextTarget()\n",
    "\n",
    "# Initialize the PDFConverter with the existing PDF and injection items\n",
    "pdf_converter = PromptConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        PDFConverter(\n",
    "            prompt_template=None,  # No template provided\n",
    "            font_type=\"Arial\",\n",
    "            font_size=12,\n",
    "            page_width=210,\n",
    "            page_height=297,\n",
    "            existing_pdf=cv_pdf_path,  # Provide the existing PDF\n",
    "            injection_items=injection_items,  # Provide the injection items\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=pdf_converter,\n",
    ")\n",
    "\n",
    "# Initialize the attack\n",
    "attack = PromptSendingAttack(\n",
    "    objective_target=prompt_target,\n",
    "    attack_converter_config=converter_config,\n",
    ")\n",
    "\n",
    "result = await attack.execute_async(objective=prompt)  # type: ignore\n",
    "await ConsoleAttackResultPrinter().print_conversation_async(result=result)  # type: ignore"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
